﻿using System;

namespace iron_py
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("====Example 00 HelloWorld====");
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine(":IronPython 基本初始化 需引用包IronPython  和  DynamicLanguageRuntime");
            HelloWorld();
            Console.WriteLine();
            Console.WriteLine();

            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("====Example 01 Base64====");
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine(":IronPython 调用标准库 另需引用包IronPython.Stdlib");
            Base64();
            Console.WriteLine();
            Console.WriteLine();

            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("====Example 02 Base64====");
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine(":IronPython c#传递参数给python  以及取得python返回值");
            ShareVar();
            Console.WriteLine();
            Console.WriteLine();

            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("====Example 03 PythonCallSharp====");
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine(":IronPython c#传递函数给python使用");
            PythonCallSharp();
            Console.WriteLine();
            Console.WriteLine();


            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("====Example 04 SharpCallPythonModule====");
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine(":c# 模块化调用python");
            SharpCallPythonModule();
            Console.WriteLine();
            Console.WriteLine();


            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("====Example 05 SharpCallPythonModule2====");
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine(":c# 模块化调用python 第二种");
            SharpCallPythonModule2();
            Console.WriteLine();
            Console.WriteLine();

            Console.ReadLine();
        }


        static void HelloWorld()
        {
            var pythonEngine = IronPython.Hosting.Python.CreateEngine();


            //python 空格是语法的一部分
            var pycode = @"
srcstr = b'Hello World From Python!'
print('src str: ' + str(srcstr))
";

            Console.WriteLine("python srccode:");
            Console.WriteLine("<--");
            Console.WriteLine(pycode);
            Console.WriteLine("-->");

            var pythonScripts = pythonEngine.CreateScriptSourceFromString(pycode);

            Console.WriteLine("python Execute:");
            Console.WriteLine("<--");
            pythonScripts.Execute();
            Console.WriteLine("-->");
        }

        static void Base64()
        {
            var pythonEngine = IronPython.Hosting.Python.CreateEngine();

            //python 空格是语法的一部分
            var pycode = @"
import base64

srcstr = b'Hello World From Python!'
print('src str: ' + str(srcstr))

tobase = base64.b64encode(srcstr)
print('base64 str: ' + str(tobase))
";
            Console.WriteLine("python srccode:");
            Console.WriteLine("<--");
            Console.WriteLine(pycode);
            Console.WriteLine("-->");

            var pythonScripts = pythonEngine.CreateScriptSourceFromString(pycode);

            Console.WriteLine("python Execute:");
            Console.WriteLine("<--");
            pythonScripts.Execute();
            Console.WriteLine("-->");
        }

        static void ShareVar()
        {
            var pythonEngine = IronPython.Hosting.Python.CreateEngine();

            //python 空格是语法的一部分
            var pycode = @"
import base64

srcstr = str1 + '  ' + str2
print('src str: ' + str(srcstr))

tobase = base64.b64encode(srcstr)
print('base64 str: ' + str(tobase))
";
            Console.WriteLine("python srccode:");
            Console.WriteLine("<--");
            Console.WriteLine(pycode);
            Console.WriteLine("-->");

            var pythonScripts = pythonEngine.CreateScriptSourceFromString(pycode);
            var scope = pythonEngine.CreateScope();
            scope.SetVariable("str1", "武汉");
            scope.SetVariable("str2", "加油");

            Console.WriteLine("python Execute:");
            Console.WriteLine("<--");
            var r = pythonScripts.Execute(scope);//通过scope 传入参数

            //执行完毕后通过scope取得变量值
            if (scope.TryGetVariable("tobase", out string value))
            {
                Console.WriteLine("python result tobase=:" + value);
            }
            Console.WriteLine("-->");
        }


        static void PythonCallSharp()
        {

            var pythonEngine = IronPython.Hosting.Python.CreateEngine();

            //python 空格是语法的一部分
            //不需要c#端做什么， 从pycode里面导入c# 函数
            //这里用到的 class ForPy，调用他的静态函数  ForPy.goodday 
            var pycode = @"

import clr

clr.AddReferenceByPartialName('iron_py') #导入一个c#命名空间对应的dll
from iron_py import ForPy #import   iron_py.ForPy
srcstr = ForPy.goodday('加油') #call c# 静态函数
print('src str: ' + str(srcstr))

import base64

tobase = base64.b64encode(str(srcstr))
print('base64 str: ' + str(tobase))


";
            Console.WriteLine("python srccode:");
            Console.WriteLine("<--");
            Console.WriteLine(pycode);
            Console.WriteLine("-->");

            var pythonScripts = pythonEngine.CreateScriptSourceFromString(pycode);

            Console.WriteLine("python Execute:");
            Console.WriteLine("<--");
            var r = pythonScripts.Execute();
            Console.WriteLine("-->");
        }

        static void SharpCallPythonModule()
        {
            //比较标准的作为模块导入的方式
            var pythonEngine = IronPython.Hosting.Python.CreateEngine();

            //python 空格是语法的一部分
            //这个python 定义了三个函数，他自身并没有直接执行的代码
            var pycode = @"
def PrintHelloWorld():
    print('Hello World!')

def PrintMessage(message):
    print(message)

def Add(arg1, arg2):
    return (arg1 + arg2)
";
            Console.WriteLine("--保存代码到文件");
            if ( System.IO.Directory.Exists("pymod") == false)
                System.IO.Directory.CreateDirectory("pymod");
            System.IO.File.WriteAllText("./pymod/mod1.py", pycode);
            Console.WriteLine("--配置python加载路径");
            var searchPaths = pythonEngine.GetSearchPaths();
            searchPaths.Add("./pymod");
            pythonEngine.SetSearchPaths(searchPaths);
            Console.WriteLine("--导入模块");
            var scope = IronPython.Hosting.Python.ImportModule(pythonEngine, "mod1");

            Console.WriteLine("--调用");
            dynamic PrintHelloWorld = scope.GetVariable("PrintHelloWorld");
            PrintHelloWorld();
            dynamic PrintMessage = scope.GetVariable("PrintMessage");
            PrintMessage("加油武汉");
            dynamic Add = scope.GetVariable("Add");
            Console.WriteLine("call Add(1,2)=" + Add(1, 2));
        }

        static void SharpCallPythonModule2()
        {            
            //执行一次后从scope中取出函数调用，对于简单的情况可以，自行选择

            var pythonEngine = IronPython.Hosting.Python.CreateEngine();

            //python 空格是语法的一部分
            //这个python 定义了三个函数，他自身并没有直接执行的代码
            var pycode = @"
def PrintHelloWorld():
    print('Hello World!')

def PrintMessage(message):
    print(message)

def Add(arg1, arg2):
    return (arg1 + arg2)
";
            var pythonScripts = pythonEngine.CreateScriptSourceFromString(pycode);
            var scope = pythonEngine.CreateScope();
            pythonScripts.Execute(scope);
            Console.WriteLine("--调用");
            dynamic PrintHelloWorld = scope.GetVariable("PrintHelloWorld");
            PrintHelloWorld();
            dynamic PrintMessage = scope.GetVariable("PrintMessage");
            PrintMessage("加油武汉");
            dynamic Add = scope.GetVariable("Add");
            Console.WriteLine("call Add(1,2)=" + Add(1, 2));
        }
    }
    public class ForPy
    {
        public static void goodday(string str)
        {
            Console.WriteLine("this is a c# function GoodDay:" + str);

        }
    }
}
